import type { ButtonProps } from "element-plus";
import type { PropType, VNodeChild } from "vue";
import { ElMessageBox } from "element-plus";
import { computed, defineComponent } from "vue";
import { $t } from "@/plugins/i18n";

interface Props extends Partial<ButtonProps> {
    /** 是否使用 ElMessageBox */
    isBox?: boolean;
    /** 提示内容 */
    tip?: string;
    /** Popconfirm 出现位置 */
    placement?: string;
    /** Popconfirm 提示宽度, 仅在 Popconfirm 模式下生效 */
    tipWidth?: number | string;
}

/** 通用删除按钮, 支持 Popconfirm 和 ElMessageBox 两种模式 */
export default defineComponent(
    (props: Props, { emit, attrs }) => {
        const tip = computed(() => props.tip || $t("description.deleteConfirm"));

        const openBox = (): void => {
            if (!props.isBox) return;
            ElMessageBox.confirm(
                tip.value,
                $t("button.delete"),
                {
                    type: "warning",
                    customClass: "align-baseline!",
                },
            ).then(() => {
                emit("confirm");
            });
        };

        /** 删除按钮 */
        const deleteBtn = (): VNodeChild => (
            <el-button
                {...attrs}
                type={props.type}
                link={props.link}
                loading={props.loading}
                onClick={openBox}
            >
                {$t("button.delete")}
            </el-button>
        );

        return () => (
            props.isBox
                ? deleteBtn()
                : (
                        <el-popconfirm
                            width={props.tipWidth}
                            title={tip.value}
                            placement={props.placement}
                            onConfirm={() => { emit("confirm"); }}
                        >
                            {{
                                reference: deleteBtn,
                            }}
                        </el-popconfirm>
                    )
        );
    },
    {
        name: "ElDeleteButton",
        props: {
            isBox: {
                /**
                 * Note[vue] 这里需要显式声明 type, 否则当直接传入 isBox 时为空字符串("")
                 * 虽然不写 type 会通过上面给定的 Props 接口进行类型推断
                 * 但最好都显式声明 type, 避免类似问题
                 */
                type: Boolean,
                default: false,
            },
            placement: {
                type: String,
                default: "top",
            },
            tip: {
                type: String,
                default: "",
            },
            tipWidth: {
                type: [Number, String] as PropType<number | string>,
                default: 160,
            },
            type: {
                type: String as PropType<ButtonProps["type"]>,
                default: "danger",
            },
            link: {
                type: Boolean,
                default: true,
            },
            loading: {
                type: Boolean,
                default: false,
            },
        },
        emits: {
            /** 确认删除 */
            confirm: () => true,
        },
    },
);
